Android 动态库/静态库(.a|.so)

名词解析

文件格式 文件后缀 说明
Obj文件 .o .C .cpp文件编译之后的中间文件
静态库 .a 相当于WindowsLib文件,Obj文件的集合,(不便于更新扩展)
动态库 .so 相当于WindowsDll文件,Obj文件链接的可执行文件(方便更新)

延时加载: 在加载动态库时,不进行全部导入, 在调用API时,发现动态库没有加载,临时加载动态库


静态库生成

Ar文件打包Lib(.o文件)

命令 功能
t 查询Lib中的Obj列表
r 增加或替换Lib中的Obj文件
d 删除Lib中的Obj文件
1
ar [option] [TargetFile(`.a`)] [SourceFile(`.o`)]

动态库生成

-fpic 选项, GCC编译位置无关的代码

1
2
gcc -g -c -fpic -Wall [SourceFile(*.c)]       //编译生成地址无关的代码  
gcc -g -shared [SourceFile(*.o)] [TargetFile(*.so)] //链接生成动态库

静态库使用

在连接的时候,把.a 文件直接当作Obj 链接到目标程序中

动态库使用

函数名 作用
dlopen 相当于WindowsLoadLibrary功能, 加载一个动态库
dlsym 相当于WindowsGetPorcAddress功能, 获取动态库的一个导出函数的地址
dlclose 相当于WindowsFreeLibrary功能,卸载一个动态库
dlerror 获取一个动态库的错误信息, 相当于strerror功能,返回一个字符串

Android系统中 Libc.so 并没有导出dlopen函数, 在libdl.so文件中导出,需要手动链接libdl.so

搜索路径

  1. system/lib //系统Lib目录
  2. usr/lib //用户Lib目录
  3. data/data/PacketName/lib //包目录下的Lib目录

ReadElf

命令 功能
-d 查看导入模块(Type字段为needed则为导入库名)
--dyn-syms 列入导入导出函数或数据(有偏移 有大小则为导出, 无大小则为导入)

动态库不导出函数

动态库的入口(无关导出与否,都会调用)

旧出入口:
_init: 加载动态库会调用
_fini: 卸载动态库会调用

新出入口:

定义为入口函数的声明:__attribute__(([Type]))

Type字段可选:ConStructor (构造,_init功能)与DeStructor(析构,_fini功能)

新出入口相对于旧出入口:函数命名更见灵活,被调用次数更多


Tips:

stat结构的st_nLink字段,表示是否为一个符号链接
getPwUid获取用户名
getGrGid获取组名

文章目录
  1. 1. 名词解析
  2. 2. 静态库生成
  3. 3. 动态库生成
  4. 4. 静态库使用
  5. 5. 动态库使用
  6. 6. 搜索路径
  7. 7. ReadElf
  8. 8. 动态库不导出函数
  9. 9. 动态库的入口(无关导出与否,都会调用)
  10. 10. Tips:
|